package com.lerays.spider.sougou.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.lerays.spider.sougou.SougouSpider;

/**
 * spider server 
 * 
 * @author chenxin<chenxin619315@gmail.com>
 */
public class SpiderServer 
{
	//default server port
	public static int DEFAULT_PORT = 33770;
	
	/**
	 * server resources 
	 */
	private int port = 0;
	private ServerSocket serverSocket = null;
	private ExecutorService threadPool = null;
	private Thread acceptThread = null;
	
	//command executor
	private CommandExecutor commandExecutor = null;
	
	//wechat spider
	private SougouSpider spider = null;
	
	public SpiderServer()
	{
		this(DEFAULT_PORT);
	}
	
	public SpiderServer( int port )
	{
		this.port = port;
	}
	
	/**
	 * initialize the server <br />
	 * 1. create the server socket
	 * 2. prepare the thread pool 
	 */
	public SpiderServer init()
	{
		try {
			serverSocket = new ServerSocket(port);
			threadPool = Executors.newCachedThreadPool();
			
			commandExecutor = new CommandExecutor(this);
			spider = new SougouSpider();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return this;
	}
	
	public SougouSpider getSpider() 
	{
		return spider;
	}

	public SpiderServer setSpider(SougouSpider spider) 
	{
		this.spider = spider;
		return this;
	}

	public CommandExecutor getCommandExecutor() 
	{
		return commandExecutor;
	}

	public SpiderServer setCommandExecutor(
			CommandExecutor commandExecutor) 
	{
		this.commandExecutor = commandExecutor;
		return this;
	}

	/**
	 * start the server. <br />
	 * 1. initialize the spider
	 * 2. start the client accept thread
	 */
	public void start()
	{
		if ( serverSocket == null )
		{
			return;
		}
		
		//start the main spider
		spider.start();
		
		//start the client accept thread
		acceptThread = new Thread(new Runnable(){
			@Override
			public void run() 
			{
				while ( true ) {
					try {
						Socket socket = serverSocket.accept();
						
						/*
						 * accept the connection of the client
						 * and start a client bean to handler it request 
						 */
						threadPool.execute(new ClientBean(SpiderServer.this, socket));
					} catch (IOException e) {
						//e.printStackTrace();
					}
				}
			}
		});
		
		acceptThread.start();
	}
	
	/**
	 * shutdown the server. <br />
	 * 1. close the server socket
	 * 2. shutdown the spider
	 * 3. shutdown the thread pool
	 */
	public void shutdown()
	{
		try {
			serverSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		spider.shutdown();
		threadPool.shutdown();
	}

	public static void main(String[] args) 
	{
		SpiderServer server = new SpiderServer();
		server.init().start();
		System.out.println("[Info]: server started!");
	}
}
